// Copyright Leonid Shlyapnikov 2010
// Distributed under the GNU Lesser General Public License http://www.gnu.org/licenses/lgpl.html
//    author: Leonid Shlyapnikov, created on: Jan 30, 2010

#include "./RawData.h"

#include <boost/lexical_cast.hpp>
#include <cstring>

#include "./log.h"

namespace fixparser {

const int RawData::DEFAULT_CAPACITY = 256;

RawData::RawData(MemoryArea* const memoryArea):
        memoryArea_(memoryArea),
        capacity_(RawData::DEFAULT_CAPACITY),
        size_(0),
        data_(static_cast<char*>(memoryArea_->allocate(capacity_)))
{
}

RawData::RawData(int initial_capacity, MemoryArea* const memoryArea):
        memoryArea_(memoryArea),
        capacity_(initial_capacity),
        size_(0),
        data_(static_cast<char*>(memoryArea_->allocate(capacity_)))
{
}

RawData::~RawData() {
    delete[] this->data_;
}

inline
void
RawData::data(const char* newData, int length) {
    ensure_capacity(length);
    void* dest = reinterpret_cast<void*>(this->data_);
    const void* src = reinterpret_cast<const void*>(newData);
    ::memcpy(dest, src, length);
}

void
RawData::data(const std::string& newData) {
    this->data(newData.c_str(), newData.size());
}

inline
void
RawData::ensure_capacity(int new_capacity) {
    using boost::lexical_cast;

    if (this->capacity_ < new_capacity) {
        // get a bigger chunk of bytes, waste the previous chunk,
        // don't deallocate anything, memoryArea->reset() will handle it later
        LOG_INFO("Concider creating RawData with greater initial_capacity, current capacity: "
                << lexical_cast<std::string>(this->capacity_)
                << ", new_capacity: " << lexical_cast<std::string>(new_capacity));
        this->capacity_ = new_capacity;
        this->data_ = this->memoryArea_->allocate<char>(capacity_);
    }
}

inline
const char*
RawData::data() const {
    return this->data_;
}

template<typename T>
inline
void
RawData::writeTo(T output) const {
    output.write(this->data_, this->size_);
}

}
